package com.sunlands.zlcx.usercenter.util;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sunlands.gateway.KongClient;
import com.sunlands.zlcx.usercenter.constant.AppEnum;
import com.sunlands.zlcx.usercenter.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import okhttp3.Response;
import okhttp3.ResponseBody;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.security.MessageDigest;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * Created with meng.
 * User: meng5
 * Date: 2018-08-17
 * Description: 集团发送短信接口
 *     //http://192.168.2.11:4000/open/sms/API-document.html
 *     //http://192.168.2.11:4000/open/api-gateway/section5/serviceInvoker_v2.html
 */
@Component
@Slf4j
public class KongClientUtil {
    //发送模板短信的地址
    private static final String kongSmsTemplateUri = "/smsSend/api/tpl/sms/sendSms/sendSms";
    //测试环境
//    private static String kongDomain = "https://api-test.sunlands.com";
//    private static String kongAppKey = "zlcx_test_sms";
//    private static String kongAppSecret="oIGe8g5nJs6TcsZwBZmkMmoS5Dpb2wIR";
//    private static String kongProductSystem = "sunlands-front-longitudinal-dev";
//    private static String kongSmsTemplateId = "81910318309376";
    //正式环境
//    private static String kongDomain = "http://api-prod.sunlands.com";
//    private static String kongAppKey = "zlcx_online_sms";
//    private static String kongAppSecret="PHyTbuZJyWqJIJAPcyPhGDisjp313ewB";
//    private static String kongProductSystem = "sunlands-front-longitudinal-online";
//    private static String kongSmsTemplateId="82009173041152";
//    private static String kongSmsReportTemplateId = "116938062426112";

    @Value("${kong.domain}")
    private String kongDomain;
    @Value("${kong.appKey}")
    private String kongAppKey;
    @Value("${kong.appSecret}")
    private String kongAppSecret;
    @Value("${kong.product.system}")
    private String kongProductSystem;
    @Value("${kong.sms.template.id}")
    private String kongSmsTemplateId;

    @Value("${kong.smsreport.template.id}")
    private String kongSmsReportTemplateId;
    @Value("${kong.smsmm.template.id}")
    private String kongSmsMMTemplateId;

//    // 阿里云
//    @Value("${SMS.aliyun.accessKeyId}")
//    private String accessKeyId;//你的accessKeyId,参考本文档步骤2
//    @Value("${SMS.aliyun.accessKeySecret}")
//    private String accessKeySecret;//你的accessKeySecret，参考本文档步骤2
//    //初始化ascClient需要的几个参数
//    @Value("${SMS.product}")
//    private String product;//短信API产品名称（短信产品名固定，无需修改）
//    @Value("${SMS.domain}")
//    private String domain;//短信API产品域名（接口地址固定，无需修改）
//    @Value("${SMS.signature}")
//    private String signature;//签名
//    @Value("${SMS.mobile}")
//    private String SMSMobileKey;
//    @Value("${SMS.template.id}")
//    private String SMSTemplateId;//模板id

    public static void main(String[] args) throws IOException {
        KongClientUtil kongClientUtil = new KongClientUtil();
        String res = kongClientUtil.sendTplReport("tongzhuo","15010610692", "欢迎来尚德机构入学！");
        System.out.println(res);
    }

//    public String sendTplCheckCode(String phoneNum, String code) throws IOException{
//        //构建网关客户端
//        KongClient kongClient = new KongClient.Builder()
//                .kongUrl(kongDomain)
//                .appKey(kongAppKey)
//                .appSecret(kongAppSecret)
//                .build();
//
//        //封装参数
//        String jsonParam = buildTplParam(phoneNum, code);
//        Map<String, Object> map = new HashMap();
//        map.put("requestJson", jsonParam);
//        //发送请求
//        Response response = kongClient.postForm(kongSmsTemplateUri, map);
//
//        //返回值
//        //success:{"code":"0000","msg":"成功"}
//        //fail:{"code":"1001","msg":"无法匹配模板"}
//        ResponseBody responseBody = response.body();
//        if(responseBody == null){
//            throw new BusinessException("没有返回信息！");
//        }
//        return responseBody.string();
//    }
    //构建网关客户端
    KongClient kongClient = null;
    public String sendTplReport(String app, String phoneNum, String report) throws IOException{

        if(Objects.isNull(kongClient)){
            kongClient = new KongClient.Builder()
                    .kongUrl(kongDomain)
                    .appKey(kongAppKey)
                    .appSecret(kongAppSecret)
                    .build();
        }
        //封装参数
        String jsonParam = buildTplParam(app, phoneNum, report);
        Map<String, Object> map = new HashMap();
        map.put("requestJson", jsonParam);
        //发送请求
        Response response = kongClient.postForm(kongSmsTemplateUri, map);

        //返回值
        //success:{"code":"0000","msg":"成功"}
        //fail:{"code":"1001","msg":"无法匹配模板"}
        ResponseBody responseBody = response.body();
        if(responseBody == null){
            throw new BusinessException("没有返回信息！");
        }
        return responseBody.string();
    }

    //秘密项目发送短信
    public String sendMMCheckCode(String app, String phoneNum, String code) throws IOException{

        //构建网关客户端
        KongClient kongClient = new KongClient.Builder()
                .kongUrl(kongDomain)
                .appKey(kongAppKey)
                .appSecret(kongAppSecret)
                .build();

        //封装参数
        String jsonParam = buildMMReportParam(app, phoneNum, code);
        Map<String, Object> map = new HashMap();
        map.put("requestJson", jsonParam);
        //发送请求
        Response response = kongClient.postForm(kongSmsTemplateUri, map);

        //返回值
        //success:{"code":"0000","msg":"成功"}
        //fail:{"code":"1001","msg":"无法匹配模板"}
        ResponseBody responseBody = response.body();
        if(responseBody == null){
            throw new BusinessException("没有返回信息！");
        }
        return responseBody.string();
    }

    private String buildTplParam(String app, String phoneNum, String report){
        JSONObject params = new JSONObject();
        JSONObject head = new JSONObject();
        JSONArray array = new JSONArray();

        String productSystem = kongProductSystem;  //sunlands-front-longitudinal-dev
        String messageType = "EXTERNAL";
        int groupNum = 1;
        //TODO
        String key = "sunland";

        head.put("productSystem", productSystem);
        head.put("messageType", messageType);
        head.put("groupNum", groupNum);
        long time = System.currentTimeMillis();
        head.put("createTime", time);

        String MD5Str = md5Encrypt(productSystem + messageType + groupNum + time + key);
        //api里提供的加密方法-不好使
//        SortedMap<String, Object[]> unSignMap = new TreeMap();
//        unSignMap.put("productSystem", new Object[]{productSystem});
//        unSignMap.put("messageType", new Object[]{messageType});
//        unSignMap.put("groupNum", new Object[]{groupNum});
//        unSignMap.put("key", new Object[]{key});
//        String MD5Str = SignatureUtil.getBodyDigest(unSignMap);

        head.put("tplNumber", kongSmsTemplateId);    //模板编号
        head.put("operator", "xiyuefei");
        head.put("signData", MD5Str);

        JSONObject body = new JSONObject();
        body.put("mobile", phoneNum);
        body.put("sentType", "MESSAGE");
        JSONObject param = new JSONObject();
        param.put("report", report);
        body.put("param", param);
        //短信签名 132、考研自习室 112、同桌
        body.put("sendMarking",app.equals(AppEnum.postgraduate.name()) ? "132" : "112");
        body.put("category1", "前端纵线");
        body.put("category2", "落地页");
        body.put("category3", "");
        body.put("category4", "");
        body.put("category5", "");
        array.add(body);

        params.put("head", head);
        params.put("body", array);

        return params.toString();
    }

//    private String buildTplReportParam(String phoneNum, String report){
//        JSONObject params = new JSONObject();
//        JSONObject head = new JSONObject();
//        JSONArray array = new JSONArray();
//
//        String productSystem = kongProductSystem;  //sunlands-front-longitudinal-dev
//        String messageType = "EXTERNAL";
//        int groupNum = 1;
//        //TODO
//        String key = "sunland";
//
//        head.put("productSystem", productSystem);
//        head.put("messageType", messageType);
//        head.put("groupNum", groupNum);
//        long time = System.currentTimeMillis();
//        head.put("createTime", time);
//
//        String MD5Str = md5Encrypt(productSystem + messageType + groupNum + time + key);
//        //api里提供的加密方法-不好使
////        SortedMap<String, Object[]> unSignMap = new TreeMap();
////        unSignMap.put("productSystem", new Object[]{productSystem});
////        unSignMap.put("messageType", new Object[]{messageType});
////        unSignMap.put("groupNum", new Object[]{groupNum});
////        unSignMap.put("key", new Object[]{key});
////        String MD5Str = SignatureUtil.getBodyDigest(unSignMap);
//
//        head.put("tplNumber", kongSmsReportTemplateId);    //模板编号
//        head.put("operator", "xiyuefei");
//        head.put("signData", MD5Str);
//
//        JSONObject body = new JSONObject();
//        body.put("mobile", phoneNum);
//        body.put("sentType", "MESSAGE");
//        JSONObject param = new JSONObject();
//        param.put("report", report);
//        body.put("param", param);
//        body.put("sendMarking", "【尚德机构】");
//        body.put("category1", "前端纵线");
//        body.put("category2", "落地页");
//        body.put("category3", "");
//        body.put("category4", "");
//        body.put("category5", "");
//        array.add(body);
//
//        params.put("head", head);
//        params.put("body", array);
//
//        return params.toString();
//    }

    private String buildMMReportParam(String app, String phoneNum, String code){
        JSONObject params = new JSONObject();
        JSONObject head = new JSONObject();
        JSONArray array = new JSONArray();

        String productSystem = kongProductSystem;  //sunlands-front-longitudinal-dev
        String messageType = "EXTERNAL";
        int groupNum = 1;
        //TODO
        String key = "sunland";

        head.put("productSystem", productSystem);
        head.put("messageType", messageType);
        head.put("groupNum", groupNum);
        long time = System.currentTimeMillis();
        head.put("createTime", time);

        String MD5Str = md5Encrypt(productSystem + messageType + groupNum + time + key);
        //api里提供的加密方法-不好使
//        SortedMap<String, Object[]> unSignMap = new TreeMap();
//        unSignMap.put("productSystem", new Object[]{productSystem});
//        unSignMap.put("messageType", new Object[]{messageType});
//        unSignMap.put("groupNum", new Object[]{groupNum});
//        unSignMap.put("key", new Object[]{key});
//        String MD5Str = SignatureUtil.getBodyDigest(unSignMap);

        head.put("tplNumber", kongSmsMMTemplateId);    //模板编号
        head.put("operator", "xiyuefei");
        head.put("signData", MD5Str);

        JSONObject body = new JSONObject();
        body.put("mobile", phoneNum);
        body.put("sentType", "MESSAGE");
        JSONObject param = new JSONObject();
        param.put("code", code);
        body.put("param", param);
        body.put("sendMarking",app.equals(AppEnum.postgraduate.name()) ? "132" : "112");
        body.put("category1", "前端纵线");
        body.put("category2", "落地页");
        body.put("category3", "");
        body.put("category4", "");
        body.put("category5", "");
        array.add(body);

        params.put("head", head);
        params.put("body", array);

        return params.toString();
    }

    private static String md5Encrypt(String ParaData) {
        // 16进制字符
        char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
        try {
            byte[] strTemp = ParaData.getBytes("utf-8");
            MessageDigest mdTemp = MessageDigest.getInstance("MD5");
            mdTemp.update(strTemp);
            byte[] md = mdTemp.digest();
            int j = md.length;

            char str[] = new char[j * 2];
            int k = 0;
            // 遍历字节数组，位运算（位运算效率高），转换成字符放到字符数组中
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(str);
        } catch (Exception e) {
            return null;
        }
    }

//    public String sendSMS(String phoneNumber, String code) {
//
//        //设置超时时间-可自行调整
//        System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
//        System.setProperty("sun.net.client.defaultReadTimeout", "10000");
//        //初始化ascClient,暂时不支持多region（请勿修改）
//        IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId,
//                accessKeySecret);
//        try {
//            DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
//        } catch (ClientException e) {
//            e.printStackTrace();
//        }
//        IAcsClient acsClient = new DefaultAcsClient(profile);
//        //组装请求对象
//        SendSmsRequest request = new SendSmsRequest();
//        //使用post提交
//        request.setMethod(MethodType.POST);
//        //必填:待发送手机号。支持以逗号分隔的形式进行批量调用，批量上限为1000个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式；发送国际/港澳台消息时，接收号码格式为00+国际区号+号码，如“0085200000000”
//        request.setPhoneNumbers(phoneNumber);
//        //必填:短信签名-可在短信控制台中找到
//        request.setSignName(signature);
//        //必填:短信模板-可在短信控制台中找到，发送国际/港澳台消息时，请使用国际/港澳台短信模版
//        request.setTemplateCode(SMSTemplateId);
//        //可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
//        //友情提示:如果JSON中需要带换行符,请参照标准的JSON协议对换行符的要求,比如短信内容中包含\r\n的情况在JSON中需要表示成\\r\\n,否则会导致JSON在服务端解析失败
//        request.setTemplateParam("{\"code\":\""+code+"\"}");
//        //可选-上行短信扩展码(扩展码字段控制在7位或以下，无特殊需求用户请忽略此字段)
//        //request.setSmsUpExtendCode("90997");
//        //可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
//        request.setOutId("");
//        //请求失败这里会抛ClientException异常
//        SendSmsResponse sendSmsResponse = new SendSmsResponse();
//        try {
//            sendSmsResponse = acsClient.getAcsResponse(request);
//        } catch (ClientException e) {
//            e.printStackTrace();
//            log.info("SMS fail.{}",e);
//        }
//
//        if(null == sendSmsResponse || !sendSmsResponse.getCode().equals("OK")) {
//            //失败
//            log.info("sendSmsResponse.getCode() ={},",sendSmsResponse.getCode());
//            log.info("sendSmsResponse.getMessage() ={},",sendSmsResponse.getMessage());
//            throw new CheckRunException("【同桌】里云发送短信验证码失败");
//        }
//        return JSONObject.toJSONString(sendSmsResponse);
//    }

}